/*
Copyright 2008, Mark Arvidson

This file is part of EwaScorecard.

EwaScorecard is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

EwaScorecard is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with EwaScorecard.  If not, see <http://www.gnu.org/licenses/>.
 */

import java.io.*;
import java.util.*;
import javax.microedition.rms.*;

public class MeetData {

    private int numberOfEvents = 6;
    private Vector teams = new Vector();
    private String[] eventNames;
    private String meetName;
    private Date meetDate;
    private boolean hasChanged;
    private String filename;

    public MeetData(String meetName, Date meetDate, int numberOfEvents, String[] eventNames) {
        this.meetName = meetName;
        setFilename(meetName);
        this.meetDate = meetDate;
        this.numberOfEvents = numberOfEvents;
        this.eventNames = new String[numberOfEvents + 1];
        for (int i = 0; i < numberOfEvents; i++) {
            this.eventNames[i] = eventNames[i];
        }
        this.eventNames[numberOfEvents] = "AA";
    }

    public void setFilename(String filename) {
        this.filename = filename;
    }

    public String getFilename() {
        return filename;
    }

    public boolean hasChanged() {
        return hasChanged;
    }

    public String getMeetName() {
        return meetName;
    }

    public Date getMeetDate() {
        return meetDate;
    }

    public String[] getEvents() {
        return eventNames;
    }

    public String[] getTeams() {
        String[] result = new String[teams.size()];
        Enumeration namesEnum = teams.elements();
        for (int i = 0; i < result.length && namesEnum.hasMoreElements(); i++) {
            result[i] = namesEnum.nextElement().toString();
        }
        return result;
    }

    public int numberOfEvents() {
        return numberOfEvents;
    }

    public int teamCount() {
        return teams.size();
    }

    public TeamData getTeam(int index) {
        return (TeamData) teams.elementAt(index);
    }

    /*    public float rowData(int rowIndex, int columnIndex){
    if (rowIndex > teams.size())
    throw new ArrayIndexOutOfBoundsException("ArrayIndex out of bounds: expected 0.." + 
    gymnasts.size() + ", got " + rowIndex);
    if (columnIndex > numberOfEvents + 1)
    throw new ArrayIndexOutOfBoundsException("ArrayIndex out of bounds: expected 0.." + 
    (numberOfEvents + 1) + ", got " + columnIndex);
    
    return ((GymnastData)gymnasts.elementAt(rowIndex)).scores[columnIndex];
    }
     */
    public Vector teams() {
        return teams;
    }

    public void addGymnast(String team, int gymnastNumber, String name,
            float[] scores) {
        // alphabetize by team
        int index = -1;
        TeamData teamData = null;
        Enumeration elemEnum = teams.elements();
        while (teamData == null && index == -1 && elemEnum.hasMoreElements()) {
            TeamData oldData = (TeamData) elemEnum.nextElement();
            int teamCompare = team.compareTo(oldData.getName());
            if (teamCompare == 0) {
                // found it
                teamData = oldData;
            }
            if (teamCompare < 0) {
                index = teams.indexOf(oldData);
            }
        }
        if (teamData == null) {
            teamData = new TeamData(team, numberOfEvents);
            if (index == -1) {
                // append if not found
                teams.addElement(teamData);
            } else {
                // insert before found element
                teams.insertElementAt(teamData, index);
            }
        }
        hasChanged = true;
        teamData.addGymnast(gymnastNumber, name, scores);
    }

    public void storeRecord(String recordName) throws RecordStoreNotOpenException,
            InvalidRecordIDException,
            RecordStoreException,
            RecordStoreFullException,
            IOException {
        ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
        DataOutputStream dataStream = new DataOutputStream(byteStream);
        dataStream.writeInt(numberOfEvents);
        dataStream.writeUTF(meetName);
        dataStream.writeLong(meetDate.getTime());
        for (int i = 0; i < numberOfEvents; i++) {
            dataStream.writeUTF(eventNames[i]);
        }
        dataStream.writeInt(teams.size());
        Enumeration gymnastEnum = teams.elements();
        while (gymnastEnum.hasMoreElements()) {
            TeamData data = (TeamData) gymnastEnum.nextElement();
            data.storeRecord(dataStream, recordName.equals(EwaScorecard.DEFAULTS_RECORD_NAME));
        }
        dataStream.flush();
        byteStream.flush();
        byte[] bytes = byteStream.toByteArray();
        dataStream.close();
        byteStream.close();
        RecordStore store = RecordStore.openRecordStore(recordName, true);
        if (store.getNumRecords() == 0) {
            store.addRecord(bytes, 0, bytes.length);
        } else {
            store.setRecord(1, bytes, 0, bytes.length);
        }
        store.closeRecordStore();
        hasChanged = false;
    }

    public static MeetData retrieveRecord(String recordName) throws RecordStoreNotOpenException,
            InvalidRecordIDException,
            RecordStoreException,
            RecordStoreFullException,
            IOException {
        MeetData result = null;
        RecordStore store = RecordStore.openRecordStore(recordName, false);
        byte[] record = store.getRecord(1); // first record

        ByteArrayInputStream byteStream = new ByteArrayInputStream(record);
        DataInputStream dataStream = new DataInputStream(byteStream);
        byteStream.reset();
        dataStream.reset();
        int numberOfEvents = dataStream.readInt();
        String meetName = dataStream.readUTF();
        Date date = new Date(dataStream.readLong());
        String eventNames[] = new String[numberOfEvents];
        for (int i = 0; i < numberOfEvents; i++) {
            eventNames[i] = dataStream.readUTF();
        }
        result = new MeetData(meetName, date, numberOfEvents, eventNames);
        int teamSize = dataStream.readInt();
        for (int j = 0; j < teamSize; j++) {
            result.teams.addElement(TeamData.restoreRecord(dataStream));
        }
        dataStream.close();
        byteStream.close();
        store.closeRecordStore();

        //       result.updateTops();
        return result;
    }

    private float[] createScoreArray() {
        float[] scores = new float[numberOfEvents + 1];
        for (int index = 0; index < scores.length; index++) {
            scores[index] = 0;
        }
        return scores;
    }
}
